package com.example.hdz.testtimer;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author hdz
 * @date 2018/11/03
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "TestTimer";

    /**
     * Timer是单线程模式；
     * 如果在执行任务期间某个TimerTask耗时较久，那么就会影响其它任务的调度；
     * Timer的任务调度是基于绝对时间的，对系统时间敏感；修改系统时间可能会导致定时器失效
     * Timer不会捕获执行TimerTask时所抛出的异常，由于Timer是单线程，所以一旦出现异常，则线程就会终止，其他任务也得不到执行
     */
    private Timer mTimer1 = null;
    /**
     *
     */
    private CountDownTimer mTimer2;
    /**
     * 基于相对时间，不受系统时间的改变所影响
     */
    private ScheduledExecutorService mTimer3;
    private Thread mSleepThread = null;

    Button btnStartTimer1;
    Button btnStartTimer2;
    Button btnStartTimer3;
    Button btnStopTimer1;
    Button btnStopTimer2;
    Button btnStopTimer3;

    private boolean bExitThread = false;

    BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (Intent.ACTION_TIME_CHANGED.equals(action)) {
                Log.v(TAG, "====Intent.ACTION_TIME_CHANGED====");
            } else if (Intent.ACTION_DATE_CHANGED.equals(action)) {
                Log.v(TAG, "====Intent.ACTION_DATE_CHANGED====");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnStartTimer1 = (Button)findViewById(R.id.btnStartTimer1);
        btnStartTimer1.setOnClickListener(this);
        btnStopTimer1 = (Button)findViewById(R.id.btnStopTimer1);
        btnStopTimer1.setOnClickListener(this);
        btnStopTimer1.setEnabled(false);

        btnStartTimer2 = (Button)findViewById(R.id.btnStartTimer2);
        btnStartTimer2.setOnClickListener(this);
        btnStopTimer2 = (Button)findViewById(R.id.btnStopTimer2);
        btnStopTimer2.setOnClickListener(this);
        btnStopTimer2.setEnabled(false);

        btnStartTimer3 = (Button)findViewById(R.id.btnStartTimer3);
        btnStartTimer3.setOnClickListener(this);
        btnStopTimer3 = (Button)findViewById(R.id.btnStopTimer3);
        btnStopTimer3.setOnClickListener(this);
        btnStopTimer3.setEnabled(false);

        Button btnStartSleep = (Button)findViewById(R.id.btnStartSleep);
        btnStartSleep.setOnClickListener(this);
        Button btnStopSleep = (Button)findViewById(R.id.btnStopSleep);
        btnStopSleep.setOnClickListener(this);

        // 监听系统时间被修改
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_DATE_CHANGED);
        registerReceiver(mBroadcastReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(mBroadcastReceiver);
        super.onDestroy();
    }

    private void startTimer1() {
        if (mTimer1 == null) {
            mTimer1 = new Timer();
        }
        mTimer1.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(TAG, "Timer1 ========");
            }
        }, 0, 2000);
    }
    private void stopTimer1() {
        if (mTimer1 != null) {
            mTimer1.cancel();
            mTimer1 = null;
        }
    }

    private void startTimer2() {
        long millisInFuture    = 2000;
        long countDownInterval = 500;
        mTimer2 = new CountDownTimer(millisInFuture, countDownInterval) {
            @Override
            public void onTick(long l) {
                //每隔countDownInterval进入到这里
                //Log.d(TAG, "Timer2 ======"+l);
            }

            @Override
            public void onFinish() {
                //millisInFuture时间到就进到这里
                //Log.d(TAG, "Timer2 ===!!===");
                //获取当前的毫秒值
                long time = currentTimeMillis();
                Log.d(TAG, "Timer2 ===!!=== " + time);
                this.start();
            }
        };
        mTimer2.start();
    }
    private void stopTimer2() {
        if (mTimer2 != null) {
            mTimer2.cancel();
            mTimer2 = null;
        }
    }


    private void startTimer3() {
        mTimer3 = new ScheduledThreadPoolExecutor(1);
        //该方法设置了执行周期，下一次执行时间相当于是上一次的执行时间加上period，它是采用已固定的频率来执行任务
        mTimer3.scheduleAtFixedRate(new TestTimeTask(), 0, 2, TimeUnit.SECONDS);
/*        mTimer3.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "Timer3 ========");
            }
        }, 0, 2, TimeUnit.SECONDS);*/
        //0表示首次执行任务的延迟时间，2表示每次执行任务的间隔时间，TimeUnit.SECONDS执行的时间间隔数值单位
        //间隔单位毫秒：TimeUnit.MILLISECONDS
        //间隔单位秒：TimeUnit.SECONDS
        //间隔单位分钟：TimeUnit.MINUTES
        //间隔单位小时：TimeUnit.HOURS
        //间隔单位天：TimeUnit.DAYS
    }
    private void stopTimer3() {
        if (mTimer3 != null) {
            mTimer3.shutdown();
            mTimer3 = null;
        }
    }



    public static long currentTimeMillis() {
        return System.nanoTime()/1000000;
    }

    private void startSleepThread() {
        bExitThread = false;
        mSleepThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!bExitThread) {
                    try {
                        Log.e(TAG, "Sleep 1000");
                        Thread.sleep(4000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        mSleepThread.start();
    }

    private void stopSleepThread() {
        if (mSleepThread != null) {
            bExitThread = true;
            try {
                mSleepThread.join();
            } catch (Exception e) {
                e.printStackTrace();
            }
            mSleepThread = null;
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnStartTimer1:
                btnStartTimer1.setEnabled(false);
                btnStopTimer1.setEnabled(true);
                startTimer1();
                break;
            case R.id.btnStopTimer1:
                btnStartTimer1.setEnabled(true);
                btnStopTimer1.setEnabled(false);
                stopTimer1();
                break;
            case R.id.btnStartTimer2:
                btnStartTimer2.setEnabled(false);
                btnStopTimer2.setEnabled(true);
                startTimer2();
                break;
            case R.id.btnStopTimer2:
                btnStartTimer2.setEnabled(true);
                btnStopTimer2.setEnabled(false);
                stopTimer2();
                break;
            case R.id.btnStartTimer3:
                btnStartTimer3.setEnabled(false);
                btnStopTimer3.setEnabled(true);
                startTimer3();
                break;
            case R.id.btnStopTimer3:
                btnStartTimer3.setEnabled(true);
                btnStopTimer3.setEnabled(false);
                stopTimer3();
                break;
            case R.id.btnStartSleep:
                startSleepThread();
                break;
            case R.id.btnStopSleep:
                stopSleepThread();
                break;
            default:
                break;
        }
    }

    class TestTimeTask extends TimerTask{
        @Override
        public void run() {
            Log.e(TAG, "TestTimeTask!!!");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
